

#include <string.h>
#include "Log.h"
#include "BSP.h"
#include "BSP_Sleep.h"

#include "FreeRTOS.h"
#include "task.h"

#include <Utility/BitReverse.h>
#include "rfid_common.h"
#include "HIDProx.h"

/*
判断卡类型，3block或6block
3block：直接解析
6block：与之前缓存的数据对比，一样，则开始解析；否则，先缓存。
解析完成后，清除缓存。
*/
static const HIDProxDecoderParams_T hidDecoderParam = {
#if FSK_FC_Period == 1
	.longPeriodRange = {FSK_Long_Period - 1, FSK_Long_Period + 3},		//低频有效范围
	.shortPeriodRange = {FSK_Short_Period - 3, FSK_Short_Period + 0},	//高频有效范围
#else
	.longPeriodRange = {FSK_Long_Period - 2, FSK_Long_Period + 3},		//低频有效范围
	.shortPeriodRange = {FSK_Short_Period - 3, FSK_Short_Period + 1},	//高频有效范围
#endif
	.periodShort = FSK_Short_Period,	//短周期
	.periodLong = FSK_Long_Period,		//长周期
	.header_init = 0xFF,	//sof初始值
	.sync = HID_CARD_HEADER_VALUE,		//sof值
	.levelNum = HID_CARD_LONG_FRAME_SIZE - 8,		//期望接收的长度
	.lowNum = 5,			//低电平位宽
	.highNum = 6,			//高电平位宽
};

static uint32_t hidBitsContainers[4][16];
static BitSlider_T hidBitSliders[4] = {
	[0] = {.num_bundles = 16, .bundles = hidBitsContainers[0], },
	[1] = {.num_bundles = 16, .bundles = hidBitsContainers[1], },
	[2] = {.num_bundles = 16, .bundles = hidBitsContainers[2], },
	[3] = {.num_bundles = 16, .bundles = hidBitsContainers[3], },
};

static uint8_t hidbitAlloc = 0x0F;


static BitSlider_T* HIDProxBitSlider_GetFromISR(void){
	uint32_t i;
	BitSlider_T* slider = NULL;
	
	for(i = 0; i < 4; i++){
		const uint8_t mask = (1 << i);
		if(hidbitAlloc & mask){
			hidbitAlloc &= ~ mask;
			slider = &hidBitSliders[i];
			break;
		}
	}
	
	if(slider){
		BitSlider_Clear(slider, 0);
		memset(slider->bundles, 0, slider->num_bundles * sizeof(uint32_t));
	}
	return slider;
}
static BitSlider_T* HIDProxBitSlider_Get(void){
	BitSlider_T* slider;
	
	taskENTER_CRITICAL();
	slider = HIDProxBitSlider_GetFromISR();
	taskEXIT_CRITICAL();
	
	return slider;
}

static void HIDProxBitSlider_Put(BitSlider_T* slider){
	uint32_t i;
	taskENTER_CRITICAL();
	for(i = 0; i < 4; i++){
		if(&hidBitSliders[i] == slider){
			hidbitAlloc |= (1 << i);
			break;
		}
	}
	taskEXIT_CRITICAL();
}

static void HIDProxBitSlider_Init(void){
	hidbitAlloc = ~(~0u << 4u);
}

static HIDProxDecoder_T hidProx;
static uint32_t hidOutContainers[16];
static BitSlider_T hidOut = {.num_bundles = 16, .bundles = &hidOutContainers[0], };

/*------------------------------------------------------------*/
uint16_t periodBuf[256];
uint8_t periodCount;

//初始化解码器

void HIDProxDecoder_Reset(HIDProxDecoder_T* decoder){
	const HIDProxDecoderParams_T* param = decoder->param;
	memset(decoder, 0, sizeof(*decoder));
	decoder->param = param;
	decoder->header = param->header_init;
}

void HIDProxDecoder_Init(HIDProxDecoder_T* decoder, const HIDProxDecoderParams_T* param){
	decoder->param = param;
	HIDProxDecoder_Reset(decoder);
}

static void HIDProxDecoder_PrintPiont(const Piont_T* piont){
//		printf("piont(%d, %d)\n", piont->value, piont->position);
}

static void HIDProxDecoder_PrintBits(const uint8_t *bits, uint32_t length){
	printf("\nbits: ");
	for(uint32_t i = 0; i < length; i++){
		printf("%d", bits[i]);
	}
	printf("\n");
}

static inline Piont_T* HIDProxDecoder_CurTrough(HIDProxDecoder_T* decoder){
	return &decoder->troughs[decoder->curTrough & 1u];
}

static inline Piont_T* HIDProxDecoder_PrevTrough(HIDProxDecoder_T* decoder){
	return &decoder->troughs[(decoder->curTrough - 1) & 1u];
}

static inline uint16_t HIDProxDecoder_Distance(const uint16_t pos1, const uint16_t pos2){
	return (pos1 < pos2) ? (pos2 - pos1) : (pos1 - pos2);
}

static inline int HIDProxDecoder_PeriodCheck(const uint16_t period){
	if(period < (FSK_Short_Period - 3)){
		return 0;
	}
	
	if(period > (FSK_Long_Period + 3 )){
		return 0;
	}
	
	return 1;
}

//查找波谷

int HIDProxDecoder_SearchTrough(const uint16_t* data, const uint16_t offset, uint16_t length, uint16_t width, uint16_t* cursor, Piont_T* trough){
	const uint16_t* pEnd;
	const uint16_t* pTrough;
	const uint16_t* pData = data + offset;
	const uint16_t left = length - offset;
	uint16_t pos = *cursor;
	const uint16_t remain = width - pos;
	uint16_t len = DECODE_MIN(left, remain);
	int found = 0;
	
	pEnd = pData + len;
	
	if(pos == 0){
		//初始
		pTrough = &pData[0];
	}
	else{
		//上次未完成
		pTrough = &trough->value;
	}

	//查找范围内最大值和最小值
	while(pData < pEnd){
		
		if(*pTrough > *pData){
			pTrough = pData;
		}
		
		pData++;
	}

	if(pos == 0 || *pTrough != trough->value){
		trough->value = *pTrough;
		trough->position = pTrough - data;
		found = 1;
	}

	pos += len;
	
	if(pos == width){
		//查找完成
		*cursor = 0;
	}
	else{
		*cursor = pos;
	}
	
	return found;
}

static inline int HIDProxDecoder_PeriodLevel(const HIDProxDecoder_T* decoder, const uint8_t period){
	const HIDProxDecoderParams_T* param = decoder->param;
	const uint8_t* longPeriodRange = param ->longPeriodRange;
	const uint8_t* shortPeriodRange = param ->shortPeriodRange;
	if(longPeriodRange[0] <= period && period <= longPeriodRange[1]){
		//低频->高电平
		return 1;
	}
	else
	if(shortPeriodRange[0] <= period && period <= shortPeriodRange[1]){
		//高频->低电平
		return 0;
	}
	
	return -1;
}

static inline void HIDProxDecoder_SetLevel(HIDProxDecoder_T* decoder, uint8_t level){
	const HIDProxDecoderParams_T* param = decoder->param;
	if(decoder->header != param->sync){
		//匹配SOF
		decoder->header <<= 1;
		decoder->header |= level;
		if(decoder->header == param->sync){
			BitSlider_Clear(decoder->receive, 0);
		}
	}
	else{
		//保存数据位
		BitSlider_Add(decoder->receive, level);
		if(BitSlider_Length(decoder->receive) == param->levelNum){
			if(decoder->input){
				BitSlider_Clear(decoder->receive, 0);
			}
			else{
				decoder->input = decoder->receive;
				decoder->receive = HIDProxBitSlider_GetFromISR();
			}
			decoder->header = param->header_init;
		}
	}
}

static void HIDProxDecoder_PeriodToLevel(HIDProxDecoder_T* decoder, const uint8_t* periodBuf, uint8_t length){
	const HIDProxDecoderParams_T* param = decoder->param;
	const uint8_t* p = periodBuf;
	const uint8_t* pend = periodBuf + length;
	uint8_t prev = decoder->prevPeriod;
	uint8_t period;
	
	while(p < pend){
		period = *p++;
		if(prev != 0){
			uint8_t temp = period;
			period = (prev + temp) / 2;
			prev = temp;
		}
		else{
			prev = period;
		}

		int level = HIDProxDecoder_PeriodLevel(decoder, period);
		
		if(level){
			//低频->高电平
			if(decoder->highCount >= (param->highNum - 1)){
				HIDProxDecoder_SetLevel(decoder, 0);
			}
			decoder->highCount = 0;
			decoder->lowCount++;
			if(decoder->lowCount >= param->lowNum){
				decoder->lowCount = 0;
				HIDProxDecoder_SetLevel(decoder, 1);
			}
		}
		else{
			//高频->低电平
			if(decoder->lowCount >= (param->lowNum - 1)){
				HIDProxDecoder_SetLevel(decoder, 1);
			}
			decoder->lowCount = 0;
			decoder->highCount++;
			if(decoder->highCount >= param->highNum){
				decoder->highCount = 0;
				HIDProxDecoder_SetLevel(decoder, 0);
			}
		}
	}
	decoder->prevPeriod = prev;
}



void HIDProxDecoder_DecodeLevel(HIDProxDecoder_T* decoder){
	HIDProxDecoder_PeriodToLevel(decoder, decoder->periodBuf, decoder->periodCount);
}

int HIDProxDecoder_DecodeFreq(HIDProxDecoder_T* decoder, const uint16_t* data, uint16_t length){
	const HIDProxDecoderParams_T* param = decoder->param;
	const uint16_t periodShort = param->periodShort;
	const uint16_t width = periodShort + periodShort/8; //波谷搜索宽度
	uint16_t pos = 0;
	int found = 0;
	
	if(length == 0){
		return -1;
	}
	
	decoder->periodCount = 0;
	//如果还没有找到首个波，则先找到首个波
	if(decoder->state == 0){
		Piont_T* prev = HIDProxDecoder_PrevTrough(decoder);
		found = HIDProxDecoder_SearchTrough(data, pos, length, periodShort + periodShort/2, &decoder->cursor, prev);
		if(decoder->cursor){
			if(found){
				prev->position += decoder->count;
			}
			decoder->count += length;
			return -2;
		}
		if(found){
			//波谷在本次缓存中
			//波谷的1/4波长内不会出现波谷
			pos = prev->position + periodShort/4;
			prev->position += decoder->count;
		}
		else{
			//波谷在上次缓存里
			//波谷的1/4波长内不会出现波谷
			const uint32_t n = prev->position + periodShort/4;
			if(n < decoder->count){
				pos = 0;
			}
			else{
				pos = n - decoder->count;
			}
		}
		decoder->state = 1;
	}
	
	while(pos < length){
		Piont_T* cur = HIDProxDecoder_CurTrough(decoder);
		found = HIDProxDecoder_SearchTrough(data, pos,  length, width, &decoder->cursor, cur);
		if(decoder->cursor){
			if(found){
				cur->position += decoder->count;
				HIDProxDecoder_PrintPiont(cur);
			}
			break ;
		}
		
		if(found){
			//波谷在本次缓存中
			//下个波谷不会出现在本次波谷后的1/4周期内
			pos = cur->position + periodShort/4;
			cur->position += decoder->count;
		}
		else{
			//波谷在上次缓存里
			//下个波谷不会出现在本次波谷后的1/4周期内
			const uint32_t n = cur->position + periodShort/4;
			if(n < decoder->count){
				//波谷后的1/4周期还是出现在上次缓存中，则从本次数据的起始开始搜索下一个波谷
				pos = 0;
			}
			else{
				//波谷后的1/4周期还是出现在本次缓存中，则偏移到该位置
				pos = n - decoder->count;
			}
		}
		HIDProxDecoder_PrintPiont(cur);
		Piont_T* prev = HIDProxDecoder_PrevTrough(decoder);
		//当前波谷和之前波谷之间的距离为周期
		uint16_t period = HIDProxDecoder_Distance(prev->position, cur->position);
		int level = HIDProxDecoder_PeriodLevel(decoder, period);
		if(level >= 0 && 
			decoder->periodCount < sizeof(decoder->periodBuf)){
			decoder->periodBuf[decoder->periodCount++] = period;
		}
		else{
			decoder->prevPeriod = 0;
		}
		decoder->curTrough = (decoder->curTrough + 1) & 1;
	}

	decoder->count += length;
	return 0;
}

int HIDProxDecoder_Decode(HIDProxDecoder_T* decoder, const uint16_t* data, uint16_t length){
	if(!decoder->receive){
		return -1;
	}
	if(HIDProxDecoder_DecodeFreq(decoder, data, length)){
		return 0;
	}
	HIDProxDecoder_DecodeLevel(decoder);
	return 0;
}

void HIDProxDecoder_Input(const uint16_t* data, uint16_t length){
	HIDProxDecoder_Decode(&hidProx, data, length);
}



/*------------------------------------------------------*/

static void PrintSlider(const char* tag, const BitSlider_T* slider, int dir){
	DBG_WRITE("\n");
	DBG_WRITE(tag);
	DBG_WRITE("\n");
	if(dir){
		uint32_t pos = slider->head;
		while(pos < slider->tail){
			int val = BitBundles_Read(slider->bundles, pos++);
			DBG_PUT_CHAR(val ? '1' : '0');
		}
	}
	else{
		uint32_t pos = slider->tail;
		while(pos > slider->head){
			pos--;
			int val = BitBundles_Read(slider->bundles, pos);
			DBG_PUT_CHAR(val ? '1' : '0');
		}
	}
	DBG_WRITE("\n");
}

#if 0
static void HIDProx_Frame_Init(HidFrame_T* frame){
	BitSlider_Init(&frame->bits, frame->container, sizeof(frame->container)/sizeof(frame->container[0]), 0);
	frame->type = HID_FRAME_None;
	memset(frame->container, 0, sizeof(frame->container));
}
#endif 

static int HIDProx_Frame_Compare(const HidFrame_T* frame1, const HidFrame_T* frame2){
	if(frame1->type != frame2->type){
		return 1;
	}
	uint32_t len1 = BitSlider_Length(frame1->bits);
	uint32_t len2 = BitSlider_Length(frame2->bits);
	if(len1 != len2){
		return 2;
	}
	const uint32_t byteCount = len1 / 8;
	const uint8_t* data1 = (uint8_t*)frame1->bits->bundles;
	const uint8_t* data2 = (uint8_t*)frame2->bits->bundles;
	if(memcmp(data1, data2, byteCount)){
//			LOG_BUF(0, RTT_CTRL_TEXT_BRIGHT_WHITE, "data1", data1, byteCount);
//			LOG_BUF(0, RTT_CTRL_TEXT_BRIGHT_WHITE, "data2", data2, byteCount);
		return 3;
	}
	
	return 0;
}

static enum HidFrameType HIDProx_CheckFrameType(BitSlider_T* bits){
	if(BitSlider_Length(bits) != (HID_CARD_LONG_FRAME_SIZE - 8)){
		return HID_FRAME_None;
	}
/*
For 3 block tags there will be a header at the begging of the buffer and
again at the 3-block boundary (12 th bytes of the buffer).
*/
	const uint8_t * buf = (uint8_t*)bits->bundles;
	if(buf[11] == HID_CARD_SOF){
		return HID_FRAME_Short;
	}
	
	return HID_FRAME_Long;
}

static void HIDProx_Frame_Build(HidFrame_T* frame, BitSlider_T* bits){
	frame->bits = bits;
	frame->type = HIDProx_CheckFrameType(bits);
}

static void HIDProx_Frame_Destroy(HidFrame_T* frame){
	if(frame->bits){
		HIDProxBitSlider_Put(frame->bits);
		frame->bits = NULL;
	}
	frame->type = HID_FRAME_None;
}


/*------------------------------------------------------*/
static int HIDProx_DecodeManchester(HidFrame_T* frame, BitSlider_T* output){
	uint32_t *bundles = frame->bits->bundles;
	uint32_t pos = frame->bits->head;
	uint32_t tail = frame->bits->tail;
	if(frame->type == HID_FRAME_Short){
		tail = frame->bits->tail - HID_CARD_SHORT_FRAME_SIZE;
	}
	uint32_t bits[2];
	uint32_t val;
	BitSlider_Clear(output, BitSlider_MaxLength(output));
	while(pos < tail){
		bits[0] = BitBundles_Read(bundles, pos++);
		bits[1] = BitBundles_Read(bundles, pos++);
		if(bits[0] == 0 && bits[1] == 1){
			//上升沿
			val = 0;
		}
		else
		if(bits[0] == 1 && bits[1] == 0){
			//下降沿
			val = 1;
		}
		else{
			PrintSlider("Manchester error\n", frame->bits, 1);
			LOG_ERR("at: (%d: %d,%d)", pos - 2, bits[0], bits[1]);
			return -1;
		}
		BitSlider_Push(output, val);
	}
	
	return 0;
}

static int HIDProx_BitsCopy(BitSlider_T* to, BitSlider_T* from){
	if(to->num_bundles < from->num_bundles){
		return -1;
	}
	
	to->head = from->head;
	to->tail = from->tail;
	memcpy(to->bundles, from->bundles, from->num_bundles*sizeof(uint32_t));
	return 0;
}

static int HIDProx_OddCheck(uint8_t val){
	int odd = 0;
	
	for(int i = 0; i < 8; i++){
		if(val & (1 << i)){
			odd++;
		}
	}

	return (odd & 1) == 1;
}


static int HIDProx_PraseData_Standard(BitSlider_T* output){
	const uint32_t head = output->head;
	const uint32_t tail = output->tail;
	uint8_t sentinel = 0;

	while(!BitSlider_Remove(output, &sentinel)){
		if(sentinel != 0){
			return 0;
		}
	}
	
	LOGW(NULL, "sentinel NOT found!!output all bits!");
	output->head = head;
	output->tail = tail;
	return 0;
}

/*
Destron
*/
#if 0
static int HIDProx_PraseData_Destron_Do(BitSlider_T* input, BitSlider_T* output){
	uint32_t len = BitSlider_Length(input);
	if(len < 40){
		TRACE_E("input length = %d", len);
		return -2;
	}
	uint8_t val = 0;
	BitSlider_Clear(output, BitSlider_MaxLength(output)-8);
	for(int i = 0; i < 5; i++){
		BitSlider_RemoveLSB8(input, &val);
		if(!HIDProx_OddCheck(val)){
			TRACE_E("odd check fail byte(%d)!", i);
			return -3;
		}
		BitSlider_PushBits(output, val, 7, 0);
	}
	
	uint32_t head = output->head;
	uint32_t odd = 0;
	uint32_t event = 0;
	//计算结尾的奇数校验
	for(int i = 0; i < (5 * 7)/2 + 1; i++){
		if(BitBundles_Read(output->bundles, head + i)){
			odd++;
		}
	}
	//计算开头的偶校验
	for(int i = (5 * 7)/2; i < (5 * 7); i++){
		if(BitBundles_Read(output->bundles, head + i)){
			event++;
		}
	}
	
	BitSlider_Add(output, event & 1);
	BitSlider_Push(output, !(odd & 1));
	return 0;
}

static int HIDProx_PraseData_Destron(BitSlider_T* output){
	BitSlider_T* bits = HIDProxBitSlider_Get();
	if(!bits){
		TRACE_E("Alloc fail!");
		return -1;
	}
	int ret = HIDProx_PraseData_Destron_Do(output, bits);
	HIDProx_BitsCopy(output, bits);
	HIDProxBitSlider_Put(bits);
	return ret;
}
#endif 

static int HIDProx_PraseData_Destron(BitSlider_T* output){
	uint32_t containers[16];
	BitSlider_T bits = {.num_bundles = 16, .bundles = &containers[0],
			.head = sizeof(containers)*sizeof(uint32_t) - 8,
			.tail = sizeof(containers)*sizeof(uint32_t) - 8};
	uint32_t len = BitSlider_Length(output);
	if(len < 40){
		TRACE_E("output length = %d", len);
		return -2;
	}
	
	uint8_t val = 0;
	for(int i = 0; i < 5; i++){
		BitSlider_RemoveLSB8(output, &val);
		if(!HIDProx_OddCheck(val)){
			TRACE_E("odd check fail byte(%d)!", i);
			return -3;
		}
		BitSlider_PushBits(&bits, val, 7, 0);
	}
	
	uint32_t head = bits.head;
	uint32_t odd = 0;
	uint32_t event = 0;
	for(int i = 0; i < (5 * 7)/2 + 1; i++){
		if(BitBundles_Read(bits.bundles, head + i)){
			odd++;
		}
	}
	
	for(int i = (5 * 7)/2; i < (5 * 7); i++){
		if(BitBundles_Read(bits.bundles, head + i)){
			event++;
		}
	}
	
	BitSlider_Add(&bits, event & 1);
	BitSlider_Push(&bits, !(odd & 1));
	HIDProx_BitsCopy(output, &bits);
	
	return 0;
}

static int HIDProx_PraseData_80(BitSlider_T* output){
	BitSlider_T bits = *output;
	uint8_t val;
	uint8_t sum = 0;
	//check sum,include customer code
	bits.tail += 7;
	for(int i = 0; i < 11; i++){
		if(BitSlider_RemoveLSB8(&bits, &val) < 0){
			TRACE_E("Not expect end!");
			return -1;
		}
		sum += val;
	}
	uint32_t check = 0;
	if(BitSlider_RemoveBits(&bits, &check, 4, 0) < 0){
		TRACE_E("No checksum!");
		return -2;
	}
	sum &= 0x0F;
	if(check != (sum & 0x0F)){
		TRACE_E("checksum fail! check=%02X, sum = %02X", check, sum);
		return -3;
	}

	//search sentinel
	uint8_t sentinel = 0;
	while(!BitSlider_Remove(output, &sentinel)){
		if(sentinel != 0){
			return 0;
		}
	}
	
	LOGE(NULL, "sentinel NOT found!!");
	return -4;
}

static uint8_t HIDProx_PCSC_CalcLRC(BitSlider_T* bits){
	uint8_t val;
	uint8_t lrc = 0;
	for(int i = 0; i < 4; i++){
		BitSlider_PopLSB8(bits, &val);
		lrc ^= val;
	}
	
	if((lrc & 0x0F) == 0x0F){
		lrc++;
	}
	
	if(lrc == 0xFF){
		lrc = 0x00;
	}
	
	return lrc;
}

static int HIDProx_PraseData_PCSC(BitSlider_T* output){
	uint8_t sentinel = 0;
	while(!BitSlider_Remove(output, &sentinel)){
		if(sentinel != 0){
			break;
		}
	}
	
	if(BitSlider_Length(output) != 32){
		TRACE_E("data length: %d", BitSlider_Length(output));
		return -1;
	}
	
	BitSlider_T bits = *output;
	uint8_t lrc = HIDProx_PCSC_CalcLRC(&bits);
	BitSlider_PushLSB8(output, lrc);
	return 0;
}

static int HIDProx_GetCustomerCode(BitSlider_T* slider){
	const uint8_t size = 7;
	
	if(BitSlider_Length(slider) < size){
		return -1;
	}
	
	slider->tail -= size;
	uint32_t snap = 0;
	BitBundles_ReadSnap(slider->bundles, slider->tail, &snap, size, 0);
	return snap ;
}

void HIDProx_GetUID(BitSlider_T* output, uint8_t* uid, uint8_t* ulen){
	uint8_t len = 0;
	uint8_t val;
	
	while(BitSlider_RemoveLSB8(output, &val) > 0){
		uid[len++] = val;
	}
	
	uint8_t size = BitSlider_Length(output);
	if(size){
		output->tail = output->head;
		uint32_t snap = 0;
		BitBundles_ReadSnap(output->bundles, output->tail, &snap, size, 0);
		val = snap;
		uid[len++] = val << (8 - size);
	}
	
	*ulen = len;
}

int HIDProx_PraseData(BitSlider_T* output){
	int ret = 0;
	int code = HIDProx_GetCustomerCode(output);

	LOGD(NULL, "customer code:%d", code);
	/*
	Customer code 0, 1, 6, 7, 8, 63, 70, 71, 72
	Customer codes 6, 7, 8, 63, 70, and 71 are still processed as “Destron open range” tags prior to calling the clock and data transmission
	routines. 
	Customer code 72-PCSC is also processed as usual, calculating an 8-bit LRC over
	the 32 bit tag data, prior to calling the clock and data output routines. 
	*/
	switch(code){
	case 0:{
		//Standard HID 37 bit Access Control Cards  
	}
	break;
	case 1:	case 74:
	case 79: case 81:
	case 82:{
		//Standard HID 1-36 bit access control cards
		ret = HIDProx_PraseData_Standard(output);
		if(ret){
			return ret;
		}
	}
	break;
	case 6: case 7: 
	case 8: case 63: 
	case 70: case 71:{
		//@NOT Test
		//Destron tag
		ret = HIDProx_PraseData_Destron(output);
		if(ret){
			return ret;
		}
	}
	break;
	case 72:{
		ret = HIDProx_PraseData_PCSC(output);
		if(ret){
			return ret;
		}
	}
	break;
	case 80:{
		ret = HIDProx_PraseData_80(output);
		if(ret){
			return ret;
		}
	}
	break;

	default:{
		LOGE(NULL, "Unknown customer code!");
	}
	break;
	}
	PrintSlider("out", output, 0);
	return 0;
}

static int HIDProx_DecodeFrame(HidFrame_T* frame, BitSlider_T* output){
	int ret = HIDProx_DecodeManchester(frame, output);
	if(ret){
		return ret;
	}
	PrintSlider("data", output, 0);
	return HIDProx_PraseData(output);
}

//短格式帧，前半部分数据和后半部分数据相同
static int HIDProx_ShortFrameCheck(HidFrame_T* frame){
	const uint32_t n = HID_CARD_SHORT_FRAME_SIZE/8;
	const uint32_t size = HID_CARD_SHORT_FRAME_SIZE/8 - 1; //减去SOF
	const uint8_t* data = (const uint8_t*)frame->bits->bundles;
	
	return memcmp(data, data + n, size) == 0;
}

int HIDProx_DoDecode(HIDProxDecoder_T* card, BitSlider_T* output){
	HidFrame_T frameInput;
	HIDProx_Frame_Build(&frameInput, card->input);
	HidFrame_T* frame = &frameInput;
	
	enum HidFrameType type = frame->type;
	if(type == HID_FRAME_None){
		LOG_ERR("NONE Frame!");
		return -1;
	}
	
	if(type == HID_FRAME_Short){
		//直接解析3block
		LOG_DBG("SHORT Frame!");
		if(!HIDProx_ShortFrameCheck(frame)){
			LOG_ERR("Frame check fail!");
			return -2;
		}
	}
	else
	if(type == HID_FRAME_Long){
		LOG_DBG("LONG Frame!");
		if(HIDProx_Frame_Compare(frame, &card->frameBackup)){
			//缓存
			HIDProx_Frame_Destroy(&card->frameBackup);
			card->frameBackup = *frame;
			LOG_DBG("save");
			return 1;
		}
		else{
			//解析6block
		}
	}
	
	int ret = HIDProx_DecodeFrame(frame, output);
	return ret;
}


void HIDProx_Complete(BitSlider_T* receive){
	if(hidProx.input){
		hidProx.input = receive;
	}
}

void HIDProx_Init(void){
	HIDProxBitSlider_Init();
	HIDProxDecoder_Init(&hidProx, &hidDecoderParam);
	hidProx.receive = HIDProxBitSlider_Get();
}

void HIDProx_Reset(void){
	HIDProxBitSlider_Init();
	HIDProxDecoder_Reset(&hidProx);
	hidProx.receive = HIDProxBitSlider_Get();
}

int HIDProx_Read(HidProxTag_T* tag){
	int ret = -1;

	if(hidProx.input){
		ret = HIDProx_DoDecode(&hidProx, &hidOut);
		if(!ret){
			tag->type = BitSlider_Length(&hidOut);
			HIDProx_GetUID(&hidOut, tag->uid, &tag->ulen);
			LOG_BUF(0, RTT_CTRL_TEXT_BRIGHT_WHITE, "uid", tag->uid, tag->ulen);
		}
		
		if(ret <= 0){
			HIDProxBitSlider_Put(hidProx.input);
			HIDProx_Frame_Destroy(&hidProx.frameBackup);
		}
		
		hidProx.input = NULL;
		
		if(!hidProx.receive){
			hidProx.receive = HIDProxBitSlider_Get();
		}
	}
	
	return ret;
}

/*------------------------------------------------------*/



